﻿using Quartz;
using Quartz.Impl.Triggers;
using Raffles.OA.Data;
using Raffles.OA.Utility;
using SqlSugar;
using System;
using System.Reflection;
using System.Threading.Tasks;

namespace Raffles.OA.Job
{
    public class JobExecute : IJob
    {
        private static SqlSugarScope _dbContext = ReportDB.Db; 
        public void Execute(IJobExecutionContext context)
        {
            DataResult<object> obj=new DataResult<object>();
            int jobId;
            JobDataMap jobData = null;
            AutoJob dbJobEntity = null;
            bool change = false;
            try
            {
                jobData = context.JobDetail.JobDataMap;
                jobId = jobData["Id"].ToInt();
                // 获取数据库中的任务
                dbJobEntity = _dbContext.Queryable<AutoJob>().InSingle(jobId);
                if (dbJobEntity != null)
                {
                    if (dbJobEntity.EnabledMark == true && dbJobEntity.JobStatus == (int)JobStatusEnum.Run)
                    {
                        CronTriggerImpl trigger = context.Trigger as CronTriggerImpl;
                        if (trigger != null)
                        {
                            var triggerStart = trigger.StartTimeUtc.ToLocalTime().ToDate();
                            var triggerEnd = TimeZone.CurrentTimeZone.ToLocalTime(trigger.EndTimeUtc.ToDate()).ToDate();
                            if (trigger.CronExpressionString != dbJobEntity.CronExpression)
                            {
                                //更新任务周期
                                trigger.CronExpressionString = dbJobEntity.CronExpression;
                                change = true;
                            }
                            if (triggerStart.CompareTo(dbJobEntity.StartTime) != 0)
                            {
                                //更新开始时间
                                trigger.StartTimeUtc = dbJobEntity.StartTime.ToDate().ToUniversalTime();
                                change = true;
                            }
                            if (triggerEnd.CompareTo(dbJobEntity.EndTime) != 0)
                            {
                                //更新结束时间
                                trigger.EndTimeUtc = dbJobEntity.EndTime.ToDate().ToUniversalTime();
                                change = true;
                            }
                            if (change)
                            {
                               JobScheduler.GetScheduler().RescheduleJob(trigger.Key, trigger);
                            }
                            #region 执行实际任务调度
                            Assembly assembly = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory + "\\bin\\" + dbJobEntity.DllName + ".dll");
                            //获取类型,参数（名称空间+类）   
                            Type type = Type.GetType($"{dbJobEntity.DllName}.{dbJobEntity.ClassName},{dbJobEntity.DllName}");
                            //创建该对象的实例，object类型
                            object instance = Activator.CreateInstance(type);
                            MethodInfo method = type.GetMethod(dbJobEntity.FunctionName);
                            //执行函数
                            obj = (DataResult<object>)method.Invoke(instance, null);
                            #endregion
                        }
                    }
                }
            }
            catch (Exception ex)
            { 
                NLogHelper.Error(ex.ToString());
            }

            try
            {
                if (dbJobEntity != null)
                {
                    if (dbJobEntity.EnabledMark == true && dbJobEntity.JobStatus == (int)JobStatusEnum.Run)
                    {
                        DateTime? dt = null;
                        #region 更新下次运行时间
                        dbJobEntity.NextStartTime = context.NextFireTimeUtc == null ? dt : context.NextFireTimeUtc.Value.DateTime.AddHours(8);
                        dbJobEntity.UpdatedOn = DateTime.Now;
                        _dbContext.Updateable<AutoJob>(dbJobEntity).UpdateColumns(x => new { x.NextStartTime, x.UpdatedOn }).ExecuteCommand();
                        #endregion

                        #region 记录执行结果

                        if (!obj.data.IsEmpty())
                        {
                            AutoJobLog autoJobLog = new AutoJobLog()
                            {
                                JobGroupName = context.JobDetail.Key.Group,
                                JobName = context.JobDetail.Key.Name,
                                LogStatus = obj.success ? 1 : 0,
                                Remark = obj.message,
                                Extend = obj.data.ToString(),
                                CreatedOn = DateTime.Now
                            };
                            _dbContext.Insertable<AutoJobLog>(autoJobLog).ExecuteCommand();
                        }

                        #endregion
                    }
                }
            }
            catch (Exception ex)
            { 
                NLogHelper.Error(ex.ToString());
            }
        }
    }
}
